package view;

import model.Card;
import model.Player;
import model.Poker;

import javax.swing.*;
import java.awt.*;

/**
 * 扑克牌面板
 */
public class PokerPanel extends JPanel {
    private final Poker poker = new Poker();
    private final Player player = new Player();
    private final Player computer = new Player();

    // 设置电脑停止要牌的临界点
    private static final int STOP_SCORE = 18;
    private static final String PLAYER_SCORE_21 = "你的分数超过21点，你输了";
    private static final String COMPUTER_SCORE_21 = "电脑的分数超过21点，电脑输了";
    private static final String PLAYER_LOSE = "玩家输了";
    private static final String COMPUTER_LOSE = "电脑输了";
    private static final String DOG_FALL = "平局";


    public PokerPanel() {
        this.setVisible(true);
        repaint();
    }

    /**
     * 发牌，玩家点击要牌和停牌后调用
     */
    public void deal() {
        // 只要玩家要牌就发牌
        if (player.need()) { playerAddCard(); }
        if (computer.need()) {
            if (computer.score() < player.score()) {
                computerAddCard();
            } else if (player.need() && computer.score() <= STOP_SCORE) {
                computerAddCard();
            } else {
                computer.stopDeal();
            }
        }
        repaint();
    }

    /**
     * 玩家点击停牌后调用
     */
    public void playerStopDeal() {
        player.stopDeal();
    }

    /**
     * 玩家增加一张牌
     */
    private void playerAddCard() {
        player.addCard(poker.getCard());
        repaint();
        if (player.score() > 21) {
            JOptionPane.showMessageDialog(null, PLAYER_SCORE_21,
                    "提示", JOptionPane.ERROR_MESSAGE);
            // 超过21点游戏结束，设置双方停牌
            player.stopDeal();
            computer.stopDeal();
        }
    }

    /**
     * 电脑增加一张牌
     */
    private void computerAddCard() {
        computer.addCard(poker.getCard());
        repaint();
        if (computer.score() > 21) {
            JOptionPane.showMessageDialog(null, COMPUTER_SCORE_21,
                    "提示", JOptionPane.ERROR_MESSAGE);
            // 超过21点游戏结束，设置双方停牌
            player.stopDeal();
            computer.stopDeal();
        }
    }

    /**
     * 是否停止发牌，玩家和电脑都不需要牌为真
     *
     * @return 布尔值
     */
    public boolean notNeed() {
        return !player.need() && !computer.need();
    }

    /**
     * 绘制面板
     *
     * @param graphics 默认调用传入
     */
    @Override
    public void paint(Graphics graphics) {
        graphics.clearRect(0, 0, this.getWidth(), this.getHeight());
        graphics.drawString("玩家牌：", 10, 230);
        for (int i = 0; i < player.cards().size(); i++) {
            Card card = player.cards().get(i);
            graphics.drawImage(card.cardImage, 80 * i, 250, this);
        }
        graphics.drawString("电脑牌：", 10, 30);
        for (int j = 0; j < computer.cards().size(); j++) {
            Card card = computer.cards().get(j);
            graphics.drawImage(card.cardImage, 80 * j, 50, this);
        }
    }

    /**
     * 计算得分结果，提示信息后重置面板
     *
     * @return 是否成功计算结果
     */
    public boolean statistics() {
        // 当双方停止要牌才能计算结果
        if (notNeed()) {
            if (player.score() > 21) {
                JOptionPane.showMessageDialog(null, PLAYER_LOSE, "提示",
                        JOptionPane.ERROR_MESSAGE);
            } else if (computer.score() > 21) {
                JOptionPane.showMessageDialog(null, COMPUTER_LOSE, "提示",
                        JOptionPane.ERROR_MESSAGE);
            } else if (player.score() < computer.score()) {
                JOptionPane.showMessageDialog(null, PLAYER_LOSE, "提示",
                        JOptionPane.ERROR_MESSAGE);
            } else if (computer.score() > player.score()) {
                JOptionPane.showMessageDialog(null, COMPUTER_LOSE, "提示",
                        JOptionPane.ERROR_MESSAGE);
            } else {
                JOptionPane.showMessageDialog(null, DOG_FALL, "提示",
                        JOptionPane.ERROR_MESSAGE);
            }
            reset();
            return true;
        } else return false;
    }

    /**
     * 重置扑克牌游戏面板
     */
    public void reset() {
        poker.resetAndShuffle();
        player.clear();
        computer.clear();
        repaint();
    }
}